using System;
using System.Collections;
using System.Collections.Generic;


namespace LightCAD.Three
{
    public class BoxHelper : LineSegments
    {
        #region scope properties or methods
        //private static Box3 _box = new Box3();
        private static BoxHelperContext getContext()
        {
            return ThreeThreadContext.GetCurrThreadContext().BoxHelperCtx;
        }
        #endregion

        #region Properties
        public Object3D _object;
        #endregion

        #region constructor
        public BoxHelper(Object3D _object, int color = 0xffff00)
            : base(makeGeometry(), new LineBasicMaterial{ color = new Color(color), toneMapped = false })
        {
            this._object = _object;
            this.type = "BoxHelper";
            this.matrixAutoUpdate = false;
            this.update();
        }
        private static BufferGeometry makeGeometry()
        {
            var indices = new double[] { 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 };
            var positions = new double[8 * 3];
            var geometry = new BufferGeometry();
            geometry.setIndex(new BufferAttribute(indices, 1));
            geometry.setAttribute("position", new BufferAttribute(positions, 3));
            return geometry;
        }
        #endregion

        #region methods
        public void update()
        {
            var _box = getContext()._box;
            if (this._object != null)
            {
                _box.SetFromObject(this._object);
            }
            if (_box.IsEmpty()) return;
            var min = _box.Min;
            var max = _box.Max;
            /*
              5____4
            1/___0/|
            | 6__|_7
            2/___3/
            0: max.x, max.y, max.z
            1: min.x, max.y, max.z
            2: min.x, min.y, max.z
            3: max.x, min.y, max.z
            4: max.x, max.y, min.z
            5: min.x, max.y, min.z
            6: min.x, min.y, min.z
            7: max.x, min.y, min.z
            */
            var position = this.geometry.attributes["osition"];
            var array = position.array;
            array[0] = max.X; array[1] = max.Y; array[2] = max.Z;
            array[3] = min.X; array[4] = max.Y; array[5] = max.Z;
            array[6] = min.X; array[7] = min.Y; array[8] = max.Z;
            array[9] = max.X; array[10] = min.Y; array[11] = max.Z;
            array[12] = max.X; array[13] = max.Y; array[14] = min.Z;
            array[15] = min.X; array[16] = max.Y; array[17] = min.Z;
            array[18] = min.X; array[19] = min.Y; array[20] = min.Z;
            array[21] = max.X; array[22] = min.Y; array[23] = min.Z;
            position.needsUpdate = true;
            this.geometry.computeBoundingSphere();
        }
        public BoxHelper setFromObject(Object3D _object)
        {
            this._object = _object;
            this.update();
            return this;
        }
        public BoxHelper copy(BoxHelper source, bool recursive)
        {
            base.copy(source, recursive);
            this._object = source._object;
            return this;
        }
        public void dispose()
        {
            this.geometry.dispose();
            this.material.dispose();
        }
        #endregion

    }
}
